|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00019 #include "derivative.h" /* Contains type declarations */ 00020 #include "compile_options.h" 00021 #include "Central_Accel_AL.h" 00022 #include "MMA68xx.h" 00023 #include "MMA68xx_Diag.h" 00024 #include "HAL.h" 00025 #include "MailScheduler.h" 00026 #include "DSPI.h" 00027 #include "Utils.h" 00028 #include <limits.h> /* To set limits */ 00029 /* 00030 ****************************************************************************** 00031 * Constants 00032 ****************************************************************************** 00033 */ 00038 const uint16_t cau16MMA6800ResetSettings[] = 00039 { 00040 /* Sequence below is needed to perform a soft-reset */ 00041 (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | CLEAR), 00042 (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0xC0u), 00043 (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x40u), 00044 /* According to the spec, DEVSTAT should be read twice afterwards */ 00045 (MMA6800_DEVSTAT | (MMA6800_READ_REGISTER << CHAR_BIT) | CLEAR), 00046 (MMA6800_DEVSTAT | (MMA6800_READ_REGISTER << CHAR_BIT) | CLEAR)}; 00047 00048 const uint16_t cau16MMA6800InitSettings[] = 00049 { 00050 /* Configure X-axis for 150Hz, 4-pole LPF */ 00051 (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u), 00052 /* Configure Y-axis for 200Hz, 4-pole LPF */ 00053 (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au), 00054 /* Configure X-axis for ARM pulse stretch of 262msec */ 00055 (MMA6800_ARMCFGX | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x33u), /*PB */ 00056 /* Configure Y-axis for ARM pulse stretch of 262msec */ 00057 (MMA6800_ARMCFGY | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x33u), /*PB */ 00058 /* Configure X-axis Arming Threshold - Positive */ 00059 (MMA6800_ARMT_XP | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u), 00060 /* Configure Y-axis Arming Threshold - Positive */ 00061 (MMA6800_ARMT_YP | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u), 00062 /* Configure X-axis Arming Threshold - Negative */ 00063 (MMA6800_ARMT_XN | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u), 00064 /* Configure Y-axis Arming Threshold - Negative */ 00065 (MMA6800_ARMT_YN | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u), 00066 /* Configure device for PCM output, signed data, Offset monitor disabled */ 00067 /* Also, don't fix data from further changes because of CA test */ 00068 (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x15u)}; 00069 00070 const uint8_t cu8SizeofMMA6800ResetSettings = N_ELEMENTS(cau16MMA6800ResetSettings); 00071 const uint8_t cu8SizeofMMA6800InitSettings = N_ELEMENTS(cau16MMA6800InitSettings); 00072 /* 00073 ****************************************************************************** 00074 * Globals 00075 ****************************************************************************** 00076 */ 00077 /* 00078 ****************************************************************************** 00079 * vfnCAPreSchedulerInit 00080 ****************************************************************************** 00081 */ 00082 void vfnCAPreSchedulerInit(void) 00083 { 00084 /* Void */ 00085 return; 00086 } 00087 /* 00088 ****************************************************************************** 00089 * u8fnCAInit 00090 ****************************************************************************** 00091 */ 00092 uint32_t u32fnCAInit(void) 00093 { 00094 uint32_t u32Status; 00095 uint8_t u8Counter; 00096 00097 u32Status = CLEAR; 00098 u8Counter = CLEAR; 00099 00100 u32Status = (*u8pfnMMA6800BatchOp[MMA6800_TRANSFER_MODE_IS_SCHEDULED]) 00101 (MAIN_ACCELERO_SPI_CONFIG,(uint16_t*)cau16MMA6800ResetSettings, 00102 (uint16_t*)gau8MMA6800GlobalResult, 00103 (uint8_t)N_ELEMENTS(cau16MMA6800ResetSettings)); 00104 00105 DELAY_MSEC(1u); 00106 00107 u32Status = (*u8pfnMMA6800BatchOp[MMA6800_TRANSFER_MODE_IS_SCHEDULED]) 00108 (MAIN_ACCELERO_SPI_CONFIG,(uint16_t*)cau16MMA6800InitSettings, 00109 (uint16_t*)gau8MMA6800GlobalResult, 00110 (uint8_t)N_ELEMENTS(cau16MMA6800InitSettings)); 00111 00112 DELAY_MSEC(1u); 00113 00114 do 00115 { 00116 u32Status = u32fnCAInitSelfTest(); 00117 u8Counter++; 00118 }while((u32Status != CLEAR) && (u8Counter < 5)); 00119 00120 u32Status |= u8fnMMA6800WriteRegister(MAIN_ACCELERO_SPI_CONFIG, 00121 MMA6800_TRANSFER_MODE_IS_SCHEDULED, 00122 MMA6800_DEVCFG, 0x35, 00123 (uint16_t*) &gau8MMA6800GlobalResult); 00124 00125 return (u32Status); 00126 } 00127 /* 00128 ****************************************************************************** 00129 * u32fnCAScheduleAccelXY 00130 ****************************************************************************** 00131 */ 00132 uint32_t u32fnCAScheduleAccelXY(uint16_t* pu16RawDestination) 00133 { 00134 uint8_t u8Status; 00135 uint32_t u32Status; 00136 00137 u32Status = CLEAR; 00138 00139 u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 00140 MMA6800_TRANSFER_MODE_IS_SCHEDULED, 00141 (MMA6800_READ_X |MMA6800_READ_Y), 00142 CURRENT_ACCEL_MODE, pu16RawDestination, 00143 CURRENT_CA); 00144 if(CLEAR < u8Status) 00145 { 00146 u32Status = STATUS_CA_FAILED; 00147 } 00148 else 00149 { 00150 /* Nothing to do */ 00151 } 00152 00153 return(u32Status); 00154 } 00155 /* 00156 ****************************************************************************** 00157 * u32fnCAScheduleAccelXY 00158 ****************************************************************************** 00159 */ 00160 uint32_t u32fnCAScheduleAccelX(uint16_t* pu16RawDestination) 00161 { 00162 uint8_t u8Status; 00163 uint32_t u32Status; 00164 00165 u32Status = CLEAR; 00166 00167 u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 00168 MMA6800_TRANSFER_MODE_IS_SCHEDULED, 00169 MMA6800_READ_X, 00170 CURRENT_ACCEL_MODE, pu16RawDestination, 00171 CURRENT_CA); 00172 if(CLEAR < u8Status) 00173 { 00174 u32Status = STATUS_CA_FAILED; 00175 } 00176 else 00177 { 00178 /* Nothing to do */ 00179 } 00180 00181 return(u32Status); 00182 } 00183 /* 00184 ****************************************************************************** 00185 * u32fnCAScheduleAccelXY 00186 ****************************************************************************** 00187 */ 00188 uint32_t u32fnCAScheduleAccelY(uint16_t* pu16RawDestination) 00189 { 00190 uint8_t u8Status; 00191 uint32_t u32Status; 00192 00193 u32Status = CLEAR; 00194 00195 u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 00196 MMA6800_TRANSFER_MODE_IS_SCHEDULED, 00197 (MMA6800_READ_Y), 00198 CURRENT_ACCEL_MODE, pu16RawDestination, 00199 CURRENT_CA); 00200 if(CLEAR < u8Status) 00201 { 00202 u32Status = STATUS_CA_FAILED; 00203 } 00204 else 00205 { 00206 /* Nothing to do */ 00207 } 00208 00209 return(u32Status); 00210 } 00211 00212 /* 00213 ****************************************************************************** 00214 * u32fnCAExtractXY 00215 ****************************************************************************** 00216 */ 00217 uint32_t u32fnCAExtractXY(uint16_t* pu16RawSource, uint16_t* pu16FilteredXY) 00218 { 00219 /* Local variables */ 00220 uint8_t u8Status; 00221 uint32_t u32Status; 00222 uint16_t au16TempResults[RAW_MMA_ACCEL_ARRAY_SIZE]; 00223 00224 u32Status = CLEAR; 00225 u8Status = u8fnMMA6800ExtractAccelResponse(pu16RawSource, 00226 (uint16_t*)au16TempResults, 00227 RAW_MMA_ACCEL_ARRAY_SIZE, 00228 CURRENT_CA); 00229 /* Because of how Mesquite/Sycamore works, we're only interested in the */ 00230 /* second and third items of this response. We will forget the first one */ 00231 *(pu16FilteredXY++) = au16TempResults[1u]; 00232 *(pu16FilteredXY) = au16TempResults[2u]; 00233 00234 if(CLEAR != u8Status) 00235 { 00236 u32Status = STATUS_CA_FAILED; 00237 } 00238 else 00239 { 00240 /* Get out */ 00241 } 00242 00243 return (u32Status); 00244 } 00245 /* 00246 ****************************************************************************** 00247 * u32fnCAExtractX 00248 ****************************************************************************** 00249 */ 00250 uint32_t u32fnCAExtractX(uint16_t* pu16RawSource, uint16_t* pu16FilteredX) 00251 { 00252 /* Local variables */ 00253 uint8_t u8Status; 00254 uint32_t u32Status; 00255 uint16_t au16TempResults[RAW_MMA_ACCEL_ARRAY_SIZE - 1u]; 00256 00257 u32Status = CLEAR; 00258 u8Status = u8fnMMA6800ExtractAccelResponse(pu16RawSource, 00259 (uint16_t*)au16TempResults, 00260 RAW_MMA_ACCEL_ARRAY_SIZE - 1u, 00261 CURRENT_CA); 00262 /* Because of how Mesquite/Sycamore works, we're only interested in the */ 00263 /* second item of this response. We will forget the first one */ 00264 *pu16FilteredX = au16TempResults[1u]; 00265 00266 if(CLEAR != u8Status) 00267 { 00268 u32Status = STATUS_CA_FAILED; 00269 } 00270 else 00271 { 00272 /* Get out */ 00273 } 00274 00275 return (u32Status); 00276 } 00277 /* 00278 ****************************************************************************** 00279 * u32fnCAInitSelfTest 00280 ****************************************************************************** 00281 */ 00282 uint32_t u32fnCAInitSelfTest(void) 00283 { 00284 /* Declare local variables */ 00285 uint32_t u32Status; 00286 00287 /* Init local variables */ 00288 u32Status = CLEAR; 00289 00290 /* Read Part Number Register to access to sensitivity */ 00291 u32Status = u8fnMMA6800ReadRegister(MAIN_ACCELERO_SPI_CONFIG, 00292 MMA6800_TRANSFER_MODE_IS_SCHEDULED, 00293 MMA6800_PN, (uint16_t*) &gau8MMA6800GlobalResult); 00294 DELAY_MSEC(550u); 00295 00296 /**************************** Self Tests for both X and Y axis ***************************/ 00297 u32Status |= u32fnCASelfTest((uint8_t) MMA6800_READ_X); 00298 u32Status |= u32fnCASelfTest((uint8_t) MMA6800_READ_Y); 00299 00300 return(u32Status); 00301 } 00302 /* 00303 ****************************************************************************** 00304 * u32fnCAInitSelfTest 00305 ****************************************************************************** 00306 */ 00307 uint32_t u32fnCASelfTest(const uint8_t cu8Axis) 00308 { 00309 /* Declare local variables */ 00310 uint32_t u32Status; 00311 uint32_t au32FilteredSum[6]; 00312 uint32_t au32StatusErrCode[6]; 00313 uint16_t au16Raw[3]; 00314 uint16_t au16RawCross[3]; 00315 uint16_t au16OC[3]; 00316 uint16_t au16OCCross[3]; 00317 uint8_t u8Counter; 00318 00319 /* Init local variables */ 00320 u32Status = CLEAR; 00321 00322 /*Assign correct error code and correct settings for PowerOnSelfTest function*/ 00323 /*according to axis required*/ 00324 if(MMA6800_READ_X == cu8Axis) 00325 { 00326 for(u8Counter = CLEAR; u8Counter < cu8SizeofTestAmount; u8Counter++) 00327 { 00328 au32StatusErrCode[u8Counter] = cau32MMA6800ErrorCodeX[u8Counter]; 00329 if(u8Counter < cu8SizeofTestSettings) 00330 { 00331 au16Raw[u8Counter] = cau16MMA6800TestSettingsRawSelfX[u8Counter]; 00332 au16RawCross[u8Counter] = cau16MMA6800TestSettingsRawSelfY[u8Counter]; 00333 au16OC[u8Counter] = cau16MMA6800TestSettingsOCSelfX[u8Counter]; 00334 au16OCCross[u8Counter] = cau16MMA6800TestSettingsOCSelfY[u8Counter]; 00335 } 00336 } 00337 } 00338 else 00339 { 00340 for(u8Counter = CLEAR; u8Counter < cu8SizeofTestAmount; u8Counter++) 00341 { 00342 au32StatusErrCode[u8Counter] = cau32MMA6800ErrorCodeY[u8Counter]; 00343 if(u8Counter < cu8SizeofTestSettings) 00344 { 00345 au16Raw[u8Counter] = cau16MMA6800TestSettingsRawSelfY[u8Counter]; 00346 au16RawCross[u8Counter] = cau16MMA6800TestSettingsRawSelfX[u8Counter]; 00347 au16OC[u8Counter] = cau16MMA6800TestSettingsOCSelfY[u8Counter]; 00348 au16OCCross[u8Counter] = cau16MMA6800TestSettingsOCSelfX[u8Counter]; 00349 } 00350 } 00351 } 00352 00353 /**************************** Pre Self Test, Raw data *************************************/ 00354 u32Status |= u32fnMMA6800PreSelfTest((uint32_t*) &au32FilteredSum[0], 00355 (uint16_t*) cau16MMA6800TestSettingsRaw, 00356 (uint8_t) cu8SizeofTestSettings, 00357 (uint8_t) RAW_ACCEL_MODE, 00358 (uint8_t) cu8Axis, 00359 (uint16_t) CA_TEST_RAW_LIMIT_LO, 00360 (uint16_t) CA_TEST_RAW_LIMIT_HI, 00361 (uint32_t) au32StatusErrCode[0], 00362 (uint8_t) CURRENT_CA); 00363 00364 /******************************* Power On Self Test, Raw data ****************************/ 00365 u32Status |= u32fnMMA6800PowerOnSelfTest((uint32_t*) &au32FilteredSum[1], 00366 (uint16_t*) au16Raw, 00367 (uint16_t*) au16RawCross, 00368 (uint8_t) cu8SizeofTestSettings, 00369 (uint8_t) RAW_ACCEL_MODE, 00370 (uint8_t) cu8Axis, 00371 (uint32_t) au32StatusErrCode[1], 00372 (uint8_t) CURRENT_CA); 00373 00374 /*********************************** Post Self Test, Raw data ****************************/ 00375 u32Status |= u32fnMMA6800PostSelfTest((uint32_t*) &au32FilteredSum[2], 00376 (uint16_t*) cau16MMA6800TestSettingsRaw, 00377 (uint8_t) cu8SizeofTestSettings, 00378 (uint8_t) RAW_ACCEL_MODE, 00379 (uint8_t) cu8Axis, 00380 (uint32_t) au32StatusErrCode[2], 00381 (uint8_t) CURRENT_CA); 00382 00383 /**************************** Pre Self Test, OC data **************************************/ 00384 u32Status |= u32fnMMA6800PreSelfTest((uint32_t*) &au32FilteredSum[3], 00385 (uint16_t*) cau16MMA6800TestSettingsOC, 00386 (uint8_t) cu8SizeofTestSettings, 00387 (uint8_t) OC_ACCEL_MODE, 00388 (uint8_t) cu8Axis, 00389 (uint16_t) CA_TEST_OC_LIMIT_LO, 00390 (uint16_t) CA_TEST_OC_LIMIT_HI, 00391 (uint32_t) au32StatusErrCode[3], 00392 (uint8_t) CURRENT_CA); 00393 00394 /********************************* Power On Self Test, OC data ****************************/ 00395 u32Status |= u32fnMMA6800PowerOnSelfTest((uint32_t*) &au32FilteredSum[4], 00396 (uint16_t*) au16OC, 00397 (uint16_t*) au16OCCross, 00398 (uint8_t) cu8SizeofTestSettings, 00399 (uint8_t) OC_ACCEL_MODE, 00400 (uint8_t) cu8Axis, 00401 (uint32_t) au32StatusErrCode[4], 00402 (uint8_t) CURRENT_CA); 00403 00404 /*********************************** Post Self Test, OC data *******************************/ 00405 u32Status |= u32fnMMA6800PostSelfTest((uint32_t*) &au32FilteredSum[5], 00406 (uint16_t*) cau16MMA6800TestSettingsOC, 00407 (uint8_t) cu8SizeofTestSettings, 00408 (uint8_t) OC_ACCEL_MODE, 00409 (uint8_t) cu8Axis, 00410 (uint32_t) au32StatusErrCode[5], 00411 (uint8_t) CURRENT_CA); 00412 00413 return(u32Status); 00414 } 00415 /* 00416 ****************************************************************************** 00417 * 00418 * End of file. 00419 * 00420 ****************************************************************************** 00421 */